﻿using ZeroBug.EasyFlow.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace ZeroBug.EasyFlow.Motion
{
    [Serializable]
    public class Sensor : IMachineResource<IDigitalIO>, IResourceVariable
    {
        public short CardNo { get; set; }
        public short BitNo { get; set; }
        public string Description { get; set; }
        public bool LowLevelEffective { get; set; }
        public string Module { get; set; }
        public string ID { get; set; }
        [XmlIgnore]
        public IDigitalIO DigitalOperator { get; set; }
        public string OperatorName { get; set; }
        public SerializableDictionary<string, string> CsvName2Property { get; set; }
        [XmlIgnore]
        public LogHelper Logger { get; set; }
        public Sensor()
        {
            CsvName2Property = new SerializableDictionary<string, string>();
            CsvName2Property.Add("名称", nameof(Description));
            CsvName2Property.Add("所属模组", nameof(Module));
            CsvName2Property.Add("所属轴卡号", nameof(CardNo));
            CsvName2Property.Add("点位号", nameof(BitNo));
            CsvName2Property.Add("ID", nameof(ID));
        }
        public Sensor(string name)
            : this()
        {
            this.Description = name;
        }
        public Sensor(string name, short cardNo, short bitNo, bool alwaysOn, string moduleName, string id)
            : this(name)
        {
            this.CardNo = cardNo;
            this.BitNo = bitNo;
            this.LowLevelEffective = alwaysOn;
            this.Module = moduleName;
            this.ID = id;
        }
        public bool WaitOn(int waitTime = 0, bool onOff = true, int bounceTime = 0)
        {
            if (!LowLevelEffective)
            {
                if (waitTime == 0 && onOff)
                {
                    //return false;
                    //return DigitalOperator.GetInBitStatus(CardNo, BitNo);
                    return true;
                }
                else if (waitTime == 0 && !onOff)
                {
                    return !DigitalOperator.GetInBitStatus(CardNo, BitNo);
                }
                else if (onOff)
                {
                    DateTime dtnow = DateTime.Now;
                    if (DigitalOperator.GetInBitStatus(CardNo, BitNo))
                        Thread.Sleep(bounceTime);
                    while (!DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器ON{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    Thread.Sleep(bounceTime);
                    while (!DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器ON{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
                else
                {
                    DateTime dtnow = DateTime.Now;
                    if (!DigitalOperator.GetInBitStatus(CardNo, BitNo))
                        Thread.Sleep(bounceTime);
                    while (DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器OFF{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    Thread.Sleep(bounceTime);
                    while (DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器OFF{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
            }
            else
            {
                if (waitTime == 0 && onOff)
                    return !DigitalOperator.GetInBitStatus(CardNo, BitNo);
                else if (waitTime == 0 && !onOff)
                    return DigitalOperator.GetInBitStatus(CardNo, BitNo);
                else if (onOff)
                {
                    DateTime dtnow = DateTime.Now;
                    if (!DigitalOperator.GetInBitStatus(CardNo, BitNo))
                        Thread.Sleep(bounceTime);
                    while (DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器OFF{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    Thread.Sleep(bounceTime);
                    while (DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器OFF{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
                else
                {
                    DateTime dtnow = DateTime.Now;
                    if(DigitalOperator.GetInBitStatus(CardNo, BitNo))
                        Thread.Sleep(bounceTime);
                    while (!DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器ON{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    Thread.Sleep(bounceTime);
                    while (!DigitalOperator.GetInBitStatus(CardNo, BitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器ON{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
            }
        }
        [BooleanVariable]
        public bool IsOn()
        {
            return WaitOn(0, true, 0);
        }
        [BooleanVariable]
        public bool IsOff()
        {
            return WaitOn(0, false, 0);
        }
        public void SetOperator(IDigitalIO machineOperator)
        {
            this.DigitalOperator = machineOperator;
        }
    }
}
